package com.java.URL_UrlConnection.xunlei_download;

import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;
import java.text.SimpleDateFormat;
import java.util.Date;

public class XunleiServer {
    public static void main(String[] args) throws IOException {
        String path = "网络编程\\com\\java\\URL_UrlConnection\\files";
        String url = "https://pm.myapp.com/invc/xfspeed/qqpcmgr/download/QQPCDownload1530.exe";

        // 文件大小
        HttpURLConnection httpURLConnection = (HttpURLConnection) new URL(url).openConnection();
        httpURLConnection.setRequestMethod("HEAD"); // 设置请求方法
        httpURLConnection.setConnectTimeout(3000); // 设置超时间
        httpURLConnection.connect(); // 连接
        long fileSize = httpURLConnection.getContentLength();
        System.out.println("待下载文件大小为" + fileSize);

        //文件名
        SimpleDateFormat s = new SimpleDateFormat("yyyyMMddHHmmss");
        String fileName = s.format(new Date()) + url.substring(url.lastIndexOf("."));
        String fullPath = path + File.separator + fileName;

        // 创建文件
        RandomAccessFile file = new RandomAccessFile(fullPath, "rw");
        file.setLength(fileSize);
        file.close();

        // 将文件内容分散到多个线程中下载，获取每个线程要分担下载的文件大小
        int threadNum = Runtime.getRuntime().availableProcessors();
        long downloadSize = fileSize % threadNum == 0 ? fileSize / threadNum : fileSize / threadNum + 1;
        System.out.println("每个线程需下载大小为" + downloadSize);
        for (int i = 0; i < threadNum; i++) {
            new Thread(new DownLoadTask(i + 1, url, threadNum, downloadSize, fullPath)).start();
        }
    }

    static class DownLoadTask implements Runnable {
        private int order; // 线程顺序
        private String url; // 文件下载路径
        private long downloadSize; // 每个线程要分担下载的文件大小
        private long fileSize; // 整个文件大小
        private String fullPath; // 下载文件全路径

        public DownLoadTask(int order, String url, long downloadSize, long fileSize, String fullPath) {
            this.order = order;
            this.url = url;
            this.downloadSize = downloadSize;
            this.fileSize = fileSize;
            this.fullPath = fullPath;
        }

        @Override
        public void run() {
            // 计算下载的起始位置
            long start = order * downloadSize;
            long end = (order + 1) * downloadSize - 1;
            if (end > fileSize) {
                end = fileSize;
            }

            InputStream inputStream = null;
            RandomAccessFile file = null;
            try {
                // 开始下载
                HttpURLConnection httpURLConnection = (HttpURLConnection) new URL(url).openConnection();
                httpURLConnection.setRequestMethod("GET"); // 设置请求方法
                httpURLConnection.setConnectTimeout(10 * 1000); // 设置超时间
                httpURLConnection.setRequestProperty("Range", "bytes=" + start + "-" + end);
                inputStream = new BufferedInputStream(httpURLConnection.getInputStream());

                // 从开始位置开始输出文件内容
                file = new RandomAccessFile(fullPath, "rw");
                file.seek(start);

                // 开始下载
                int length = -1;
                byte[] buffer = new byte[100 * 1024];
                while ((length = inputStream.read(buffer)) != -1) {
                    file.write(buffer, 0, length);
                }
                System.out.println("线程" + order + "下载完毕");
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                if (file != null) {
                    try {
                        file.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
                if (inputStream != null) {
                    try {
                        inputStream.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }
        }
    }
}
